<?php
declare(strict_types=1);
// 用户后台导航菜单
namespace app\admin_v1\controller;

use think\facade\Db; //门面模式
use app\admin_v1\model\Menu as mysql; //导入模型

class Menu
{

    public function _Son()
    {
        // 读数据库
        $sqldb = mysql::where([['id', '>', -1]])->order("i", "desc")->select()->toArray(); //以数组方式返回
        // 1.生成树数据
        // 2.找父ID（分解成一维数组-倒序）
        $clsTree = $this->get_Tree($sqldb, 0); //生成树数据
        // $s = array_values($cateTree); //关联数组转索引数组
        $apidb = [
            'msg' => '分类',
            'code' => 2005, //状态码
            'clsTree' => $clsTree,
        ];
        return json($apidb);
    }
    //多维转为一维数组 
    function get_all_array_walk($array, $overturn = true)
    {
        $arr = [];
        array_walk_recursive($array, function ($value) use (&$arr) {
            array_push($arr, $value);
        });
        // 是否翻转
        if ($overturn) {
            $arr = array_reverse($arr, false); //翻转顺序的数组
        }
        // return json_encode($arr);
        return $arr;
    }
    // 递归获取所有的子分类----生成无限级分类树数据
    function get_Tree($db, $pid, $level = 0)
    {
        $time_int = time();
        $time = date('Y-m-d H:i:s', $time_int);
        $default = json_encode([[], $time]);
        $tree = []; //每次都声明一个新数组用来放子元素
        foreach ($db as $v) {
            if ($v['pid'] == $pid) { //匹配子记录
                // unset($v['ids']);
                $v['level'] = $level; //当前层级
                $pids = $this->get_pids($db, $v['id']); // 用自己的ID找所有祖先ID
                $v['pids'] = $this->get_all_array_walk($pids); //多维转为一维数组
                $v['pids_count'] = count($v['pids']);
                $ids = $this->get_ids($db, $v['id']); //用自己的ID找所有子孙ID
                $v['ids'] = $this->get_all_array_walk($ids, false); //多维转为一维数组
                array_unshift($v['ids'], $v['id']); //自己ID插入到数组的开头
                $v['ids_count'] = count($v['ids']);
                $v['title'] = $v['name'];
                //更新数据库
                $sqldb = mysql::where([['id', '=', $v['id']]])->find();
                $sqldb->pids = isset($v['pids']) ? json_encode([$v['pids'], $time]) : $default;
                $sqldb->ids = isset($v['ids']) ? json_encode([$v['ids'], $time]) : $default;
                $sqldb->end_node = 0; //末端节点_0否1是
                $sqldb->save();
                $v['children'] = $this->get_Tree($db, $v['id'], $level + 1); //递归获取子记录
                if ($v['children'] == null) {
                    $v['children'] = [];
                    $sqldb = mysql::where([['id', '=', $v['id']]])->find();
                    $sqldb->end_node = 1; //末端节点_0否1是
                    $sqldb->save();
                    unset($v['children']); //如果子元素为空则unset()进行删除，说明已经到该分支的最后一个元素了（可选）
                }
                if ($v['type'] == null || $v['type'] == "") {
                    unset($v['type']);
                }
                unset($v['Idx']);
                unset($v['pid']);
                unset($v['i']);
                unset($v['ids']);
                unset($v['pids']);
                unset($v['end_node']);
                unset($v['spread']);
                unset($v['level']);
                unset($v['pids_count']);
                unset($v['ids_count']);
                unset($v['name']);
                $tree[] = $v; //将记录存入新数组
            }
        }
        return $tree; //返回新数组
    }
    // 递归获取所有的子分类----生成无限级分类树数据
    function get_Tree_2($db, $pid, $level = 0)
    {
        $time_int = time();
        $time = date('Y-m-d H:i:s', $time_int);
        $default = json_encode([[], $time]);
        $tree = []; //每次都声明一个新数组用来放子元素
        foreach ($db as $v) {
            if ($v['pid'] == $pid) { //匹配子记录
                // unset($v['ids']);
                $v['level'] = $level; //当前层级
                $pids = $this->get_pids($db, $v['id']); // 用自己的ID找所有祖先ID
                $v['pids'] = $this->get_all_array_walk($pids); //多维转为一维数组
                $v['pids_count'] = count($v['pids']);
                $ids = $this->get_ids($db, $v['id']); //用自己的ID找所有子孙ID
                $v['ids'] = $this->get_all_array_walk($ids, false); //多维转为一维数组
                array_unshift($v['ids'], $v['id']); //自己ID插入到数组的开头
                $v['ids_count'] = count($v['ids']);

                // `type` varchar(255) DEFAULT NULL COMMENT 'A链接时弹窗类型blank原生跳转modal弹层外链_空值表示当前菜单不是链接',
                if ($v['type'] == null || $v['type'] == "") {
                    if ($v['pid'] == 0) {
                        $v['type2'] = "目录";
                        $v['type'] = "catalogue";
                    } else {
                        $v['type2'] = "菜单";
                        $v['type'] = "menu";

                    }
                } elseif ($v['type'] == "blank") {
                    $v['type2'] = "弹窗链接";

                } elseif ($v['type'] == "modal") {
                    $v['type2'] = "跳转链接";

                } else {
                    $v['type2'] = "";
                }


                //更新数据库
                $sqldb = mysql::where([['id', '=', $v['id']]])->find();
                $sqldb->pids = isset($v['pids']) ? json_encode([$v['pids'], $time]) : $default;
                $sqldb->ids = isset($v['ids']) ? json_encode([$v['ids'], $time]) : $default;
                $sqldb->end_node = 0; //末端节点_0否1是
                $sqldb->route_meta_title = $v["name"]; //路由meta_标题

                $sqldb->save();
                $v['children'] = $this->get_Tree_2($db, $v['id'], $level + 1); //递归获取子记录
                if ($v['children'] == null) {
                    $v['children'] = [];
                    $sqldb = mysql::where([['id', '=', $v['id']]])->find();
                    $sqldb->end_node = 1; //末端节点_0否1是
                    $sqldb->save();
                    unset($v['children']); //如果子元素为空则unset()进行删除，说明已经到该分支的最后一个元素了（可选）
                }

                // unset($v['Idx']);
                // unset($v['pid']);
                // unset($v['i']);
                // unset($v['ids']);
                // unset($v['pids']);
                // unset($v['end_node']);
                // unset($v['spread']);
                // unset($v['level']);
                // unset($v['pids_count']);
                // unset($v['ids_count']);
                // unset($v['name']);
                $tree[] = $v; //将记录存入新数组
            }
        }
        return $tree; //返回新数组
    }
    // 通过子类获取所有的父类
    function get_pids($db, $id)
    {
        $data = [];
        foreach ($db as $item) {
            if ($item['id'] == $id) {
                $arr[] = $item['id'];
                // $arr['name'] = $item['name'];
                if ($item['pid'] != 0) {
                    $arr[] = $this->get_pids($db, $item['pid']);
                    // $arr = array_merge($arr, $this->get_pids($db, $item['pid']));
                }
                $data[] = $arr;
            }
        }
        return $data;
    }
    //递归获取所有的子分类的ID
    function get_ids($array, $id)
    {
        $arr = [];
        foreach ($array as $v) {
            if ($v['pid'] == $id) {
                $arr[] = $v['id'];
                $arr = array_merge($arr, $this->get_ids($array, $v['id']));
            }
            ;
        }
        ;
        return $arr;
    }
    // 
    // 
    // 
    // 
    // 
    // 按照你的例子，我的记录全等级的方法，查父类0的素有子商品 select * from 商品 left join 分类 on (商品.分类id = 分类.id) where find_in_set(0, 分类.pids)
    // 包不包括自己其实无所谓，不包括你查的时候就要改成select * from 商品 left join 分类 on (商品.分类id = 分类.id) where 分类.id = 0 or find_in_set(0, 分类.pids)
    // 多加个 分类.id = 目标分类 or ，为了方便我都是加上自己的
    // select * from 商品 left join 分类 on (商品.分类id = 分类.id) where find_in_set(0, 分类.pids)
    // 修改 pid ，pids 永远是新的父级的 pids + 自己的id，只不过替换父级，下面自己的所有自己都要递归一遍修改 pids = 父级 pids + 自己的id
    // 新增
    public function new()
    {
        $query = request()->param(); //请求参数
        // $time_int = time();
        // $time = date('Y-m-d H:i:s', $time_int);
        $sqldb = mysql::create(
            [
                'pid' => isset($query['pid']) ? $query['pid'] : 0, //父ID
                'name' => isset($query['name']) ? $query['name'] : "未命名分类", //名称
                'i' => isset($query['i']) ? $query['i'] : 0, //排序
            ],
            // 许可写入的字段
            [
                'pid', //父ID
                'name', //名称
                'i', //排序
            ]
        );
        // unset($sqldb['sn_pw']); //删除数组中的元素
        $apidb = [
            // 'api' => ["code" => "001", "name" => "用户列表", "help" => $help], //API信息
            'code' => 200, //状态码
            'msg' => '新增成功', //状态信息
            'query' => $query, //请求参数
            // '_header' => request()->header('token'),
            // '_cache' => cache('userdb_' . request()->header('token')),
            // 'data_formerly' => $sqldb, // formerly,now/过去,现在
            'data_now' => $sqldb->toArray(),
            'data' => ['id' => $sqldb->id],
        ];
        // unset($sqldb2); //销毁
        return (json($apidb));
    }
    // 导航菜单-单项修改
    public function up()
    {
        $query = request()->param(); //请求参数
        $sqldb = mysql::where([
            ['Idx', '=', $query['Idx']],
            ['id', '=', $query['id']]
        ])->find();
        if ($sqldb) {
            if (!isset($query["type"])) {
                $type = null;
            } else if ($query["type"] == "modal") {
                $type = $query["type"];
            } else if ($query["type"] == "modal") {
                $type = $query["type"];
            } else {
                $type = null;
            }
            $sqldb->name = isset($query["name"]) ? $query["name"] : "0";//菜单名称
            $sqldb->pid = isset($query["pid"]) ? $query["pid"] : 0;//父ID
            $sqldb->show = isset($query["show"]) ? $query["show"] : 1;//展示1是0否
            $sqldb->i = isset($query["i"]) ? $query["i"] : 0;//排序
            $sqldb->icon = isset($query["icon"]) ? $query["icon"] : "layui-icon-home";//图标
            // $sqldb->end_node = isset($query["end_node"]) ? $query["end_node"] : 1;//末端节点_0否1是
            $sqldb->type = $type;//A链接时弹窗类型blank原生跳转modal弹层外链_空值表示当前菜单不是链接

            $umsg = $sqldb->save();
            if ($umsg == false) {
                return (json(['code' => 200, 'msg' => "导航菜单-单项修改-失败", 'query' => $query,]));
            }
        } else {
            return (json(['code' => 200, 'msg' => "导航菜单-数据不存在", 'query' => $query,]));
        }
        $apidb = [
            'code' => 200,
            'msg' => "导航菜单-单项修改-成功",
            'query' => $query,
        ];
        return (json($apidb));
    }

    // 原生列表树
    public function List()
    {
        // $query = request()->param(); //请求参数
        $sqldb = mysql::where([
            ['Idx', '>', 0]
        ])->order("i", "desc")
            ->select()->toArray(); //以数组方式返回
        $cateTree = $this->get_Tree_2($sqldb, 0);
        $apidb = [
            'msg' => '导航菜单-原生列表树',
            'code' => 200, //状态码
            // 'sqldb' => $sqldb,
            'db' => $cateTree,
            // 'query' => $query
        ];

        return json($apidb);
    }
    // 导航菜单-生成JSON树
    public function ListToJSON()
    {
        $sqldb = mysql::where([
            ['show', '=', 1]
        ])->order("i", "desc")
            ->select()->toArray(); //以数组方式返回
        $cateTree = $this->get_Tree($sqldb, 0);
        $apidb = [
            'msg' => '导航菜单-生成JSON树成功',
            'code' => 200, //状态码
            // 'sqldb' => $sqldb,
            // 'db' => $cateTree,

        ];
        Db::name('admin__i_user_menu_admin_json')
            ->where('user_dbid', '1001')
            ->update([
                'txt_json' => json_encode($cateTree, JSON_UNESCAPED_UNICODE), // 不编码中文
                'txt_json_unicode' => json_encode($cateTree) // 编码中文
            ]);
        return json($apidb);
    }
    //列表-JSON静态树
    public function ListJSON()
    {
        // $query = request()->param(); //请求参数
        $cateTree = Db::name('admin__i_user_menu_admin_json')
            ->where('user_dbid', '1001')
            ->find();



        $txt_json = json_decode($cateTree['txt_json']);
        $txt_json_unicode = json_decode($cateTree['txt_json_unicode']);
        if ($txt_json == null || $txt_json == null) {
            $Tree = [
                'code' => 201, //状态码
                "msg" => '数据JSON处理错误',
            ];
        } else {
            $Tree = [
                "txt_json" => $txt_json,
                "txt_json_unicode" => $txt_json_unicode,
            ];
        }
        $apidb = [
            'msg' => '静态JSON导航菜单树-此接口响应性能更好',
            'code' => 200, //状态码
            'db' => $Tree,
        ];
        return json($apidb);
    }
}
